package org.example.domain.transaction.service.mq;


import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.example.domain.transaction.adapter.repository.ITransactionRepository;
import org.example.domain.transaction.model.entity.RefundCallBackEntity;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import static org.example.types.common.MQConstants.REFUND_PRODUCER_GROUP;


/**
 * @author yinghuashen
 * @version 1.0
 * @description:
 * @date 2025/3/14 16:53
 */
@Slf4j
@Service
@RocketMQTransactionListener(txProducerGroup = REFUND_PRODUCER_GROUP)
public class RefundTransactionProducer implements RocketMQLocalTransactionListener {

    @Resource
    private ITransactionRepository transactionRepository;

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        if(!(o instanceof RefundCallBackEntity)){
            return RocketMQLocalTransactionState.ROLLBACK;
        }

        try {
            RefundCallBackEntity refundCallBackEntity = (RefundCallBackEntity) o;
            boolean executeRefund = transactionRepository.executeRefund(refundCallBackEntity.getOutTradeNo());
            if(!executeRefund){
                return RocketMQLocalTransactionState.ROLLBACK;
            }
        } catch (Exception e) {
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        return RocketMQLocalTransactionState.COMMIT;
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        try {
            Object payload = message.getPayload();
            if(!(payload instanceof RefundCallBackEntity)){
                return RocketMQLocalTransactionState.ROLLBACK;
            }

            RefundCallBackEntity refundCallBackEntity = (RefundCallBackEntity) payload;
            // 检查数据库中外部交易单是否已经修改为退款状态
            boolean isRefunded = transactionRepository.checkRefunded(refundCallBackEntity.getOutTradeNo());
            if(isRefunded){
                return RocketMQLocalTransactionState.COMMIT;
            }
            else{
                transactionRepository.saveRefundCallbackMsg(refundCallBackEntity);
                return RocketMQLocalTransactionState.ROLLBACK;
            }
        } catch (Exception e) {
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }
}
